<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  
  
  <title>闭包 | 漠北烟云</title>
  <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
  <meta name="description" content="我曾踏足山巅，也曾进入低谷，二者都让我受益良多闭包问题非常常见，被问到的频率也非常高，我也拿这个问过别人，不过大家都不太想听到关于概念背诵，关于百度出来的答案：闭包就是能够读取其他函数内部变量的函数，很准确却也没什么大用。大家更想听到更深入的理解和应用。我认为应该包括的点：作用域、作用域链、变量提升、暂时性死区、执行上下文、词法作用域。说一个简单的代码如下： 1234567891011121314">
<meta property="og:type" content="article">
<meta property="og:title" content="闭包">
<meta property="og:url" content="http://example.com/2023/03/26/%E9%97%AD%E5%8C%85/index.html">
<meta property="og:site_name" content="漠北烟云">
<meta property="og:description" content="我曾踏足山巅，也曾进入低谷，二者都让我受益良多闭包问题非常常见，被问到的频率也非常高，我也拿这个问过别人，不过大家都不太想听到关于概念背诵，关于百度出来的答案：闭包就是能够读取其他函数内部变量的函数，很准确却也没什么大用。大家更想听到更深入的理解和应用。我认为应该包括的点：作用域、作用域链、变量提升、暂时性死区、执行上下文、词法作用域。说一个简单的代码如下： 1234567891011121314">
<meta property="og:locale" content="en_US">
<meta property="article:published_time" content="2023-03-26T14:54:31.835Z">
<meta property="article:modified_time" content="2023-03-26T14:54:31.836Z">
<meta property="article:author" content="mobeiyanyun">
<meta name="twitter:card" content="summary">
  
    <link rel="alternate" href="/atom.xml" title="漠北烟云" type="application/atom+xml">
  
  
    <link rel="shortcut icon" href="/favicon.png">
  
  
    
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/typeface-source-code-pro@0.0.71/index.min.css">

  
  
<link rel="stylesheet" href="/css/style.css">

  
    
<link rel="stylesheet" href="/fancybox/jquery.fancybox.min.css">

  
<meta name="generator" content="Hexo 6.3.0"></head>

<body>
  <div id="container">
    <div id="wrap">
      <header id="header">
  <div id="banner"></div>
  <div id="header-outer" class="outer">
    <div id="header-title" class="inner">
      <h1 id="logo-wrap">
        <a href="/" id="logo">漠北烟云</a>
      </h1>
      
    </div>
    <div id="header-inner" class="inner">
      <nav id="main-nav">
        <a id="main-nav-toggle" class="nav-icon"></a>
        
          <a class="main-nav-link" href="/">Home</a>
        
          <a class="main-nav-link" href="/archives">Archives</a>
        
      </nav>
      <nav id="sub-nav">
        
          <a id="nav-rss-link" class="nav-icon" href="/atom.xml" title="RSS Feed"></a>
        
        <a id="nav-search-btn" class="nav-icon" title="Search"></a>
      </nav>
      <div id="search-form-wrap">
        <form action="//google.com/search" method="get" accept-charset="UTF-8" class="search-form"><input type="search" name="q" class="search-form-input" placeholder="Search"><button type="submit" class="search-form-submit">&#xF002;</button><input type="hidden" name="sitesearch" value="http://example.com"></form>
      </div>
    </div>
  </div>
</header>

      <div class="outer">
        <section id="main"><article id="post-闭包" class="h-entry article article-type-post" itemprop="blogPost" itemscope itemtype="https://schema.org/BlogPosting">
  <div class="article-meta">
    <a href="/2023/03/26/%E9%97%AD%E5%8C%85/" class="article-date">
  <time class="dt-published" datetime="2023-03-26T14:54:31.835Z" itemprop="datePublished">2023-03-26</time>
</a>
    
  </div>
  <div class="article-inner">
    
    
      <header class="article-header">
        
  
    <h1 class="p-name article-title" itemprop="headline name">
      闭包
    </h1>
  

      </header>
    
    <div class="e-content article-entry" itemprop="articleBody">
      
        <h3 id="我曾踏足山巅，也曾进入低谷，二者都让我受益良多"><a href="#我曾踏足山巅，也曾进入低谷，二者都让我受益良多" class="headerlink" title="我曾踏足山巅，也曾进入低谷，二者都让我受益良多"></a>我曾踏足山巅，也曾进入低谷，二者都让我受益良多</h3><p>闭包问题非常常见，被问到的频率也非常高，我也拿这个问过别人，不过大家都不太想听到关于概念背诵，关于百度出来的答案：闭包就是能够读取其他函数内部变量的函数，很准确却也没什么大用。大家更想听到更深入的理解和应用。我认为应该包括的点：作用域、作用域链、变量提升、暂时性死区、执行上下文、词法作用域。<br>说一个简单的代码如下：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">其实他包括了两个东西编译和执行编译时执行声明var a 在作用域中找 a执行阶段将1赋值给a如过找不到就继续往上找这便形成了所谓的作用域链。目前在javascript中形成了三种作用域：全局作用域、函数作用域、块作用域。</span><br><span class="line"></span><br><span class="line">``` bash</span><br><span class="line">var a = 1; // 全局作用域内的变量</span><br><span class="line">// 函数作用域</span><br><span class="line">function A() &#123;</span><br><span class="line">  var b=2</span><br><span class="line">  console.log(a);</span><br><span class="line">&#125;</span><br><span class="line">// 块作用域</span><br><span class="line">&#123;</span><br><span class="line">    a = 3</span><br><span class="line">&#125;</span><br><span class="line">A(); // 输出 &#x27;3&#x27;</span><br><span class="line">console.log(&quot;b---&quot;,b);//报错 is not defined</span><br></pre></td></tr></table></figure>

<p>变量b由于被放在了 A（）中因此 在全局并读不到他，而在块作用域中a在赋值时向上查找到了已经被声明的并且重新的赋值故而输出了3，到这里就要提下ES6中的概念 let和const</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">var a = 1; // 全局作用域内的变量</span><br><span class="line">// 函数作用域</span><br><span class="line"><span class="keyword">function</span> <span class="function"><span class="title">A</span></span>() &#123;</span><br><span class="line">  var b=2</span><br><span class="line">  console.log(a);</span><br><span class="line">&#125;</span><br><span class="line">// 块作用域</span><br><span class="line">&#123;</span><br><span class="line">    <span class="built_in">let</span> a = 3</span><br><span class="line">&#125;</span><br><span class="line">A(); // 输出 <span class="string">&#x27;1&#x27;</span></span><br><span class="line">console.log(<span class="string">&quot;b---&quot;</span>,b);//报错 is not defined</span><br></pre></td></tr></table></figure>
<p>在使用let时块级作用域下的ab并不会想上查找故而输出1<br>另一个概念是作用域模型，js 遵循的是静态作用域模型，有些地方会提到词法作用域其实指的就是静态作用域，不同的叫法，他们其实指的就是js中最常见的作用域而已。提到这里很多人又会问怎么改变作用域，通常就是 with 和 eval 这两个杀敌一千自损一万的东西。</p>
<p>with:</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">var num = &#123;</span><br><span class="line">  a: 1,</span><br><span class="line">  b: 2</span><br><span class="line">&#125;</span><br><span class="line">// with 可以帮我们省去写前缀的时间</span><br><span class="line">with(num) &#123;</span><br><span class="line">  console.log(a)</span><br><span class="line">  console.log(b)</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>with 会原地创建一个全新的作用域，这个作用域内的变量集合，其实就是传入 with 的目标对象的属性集合。因为 “创建” 这个动作，是在 with 代码实际已经被执行后发生的，所以这个新作用域确实是在运行时被添加的， with 因此也实现了对书写阶段就划分好的作用域进行修改<br> eval:</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">function</span> evalfn(num) &#123;</span><br><span class="line">  <span class="built_in">eval</span>(num)</span><br><span class="line">  console.log(a)</span><br><span class="line">&#125;</span><br><span class="line">var a = 1</span><br><span class="line">var b = <span class="string">&#x27;var a = 2&#x27;</span></span><br><span class="line">evalfn(b) //输出 2</span><br></pre></td></tr></table></figure>
<p>不难看出eval其实接受了一个字符串把它当作js代码执行也就时上面的相当于：</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">function</span> evalfn(num) &#123;</span><br><span class="line">  var a = 2</span><br><span class="line">  console.log(a)</span><br><span class="line">&#125;</span><br><span class="line">var a = 1</span><br><span class="line">evalfn(b) //输出 2</span><br></pre></td></tr></table></figure>
<p>也可以看出这些，要么创建新的作用域或者代人自己本身，都没有真正的改变作用域模型。早就没人用了，而且对性能消耗极大。知道个大概就可以。<br>以上概念知晓后，在去了解闭包才有了意义</p>
<p>1、获取函数内部的局部变量</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">function</span> <span class="function"><span class="title">f1</span></span>()&#123;</span><br><span class="line">　　var n=999;</span><br><span class="line">　　　　<span class="keyword">function</span> <span class="function"><span class="title">f2</span></span>()&#123;</span><br><span class="line">　　　　　　<span class="built_in">return</span> n</span><br><span class="line">　　　　&#125;</span><br><span class="line">    <span class="built_in">return</span> f2</span><br><span class="line">&#125;</span><br><span class="line">f1()</span><br></pre></td></tr></table></figure>
<p>在上面的代码中，函数f2就被包括在f1函数内部，这时f1内部的所有局部变量，对f2都是可见的，反之就不行在f1中返回 f2 如此我们便在f1外就访问到了f1内的私有变量。</p>
<p>2、储存变量<br>由于js的垃圾回收机制，变量会被清除，在上面的函数中由于f1是f2的父函数，而f2被赋给了一个全局变量，这导致f2始终在内存中，而f2的存在依赖于f1，因此f1也始终在内存中，不会在调用结束后，被垃圾回收机制（garbage collection）回收。</p>
<p>3、模拟私有变量<br>在JS中其实没有java 中的私有变量的概念，一些私有变量，我们希望它只能在对象内部生效，外部从外部触及，这时我们需要用到闭包了，把私有变量的作用域保护起来</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line">var book = (<span class="function"><span class="title">function</span></span>()&#123;</span><br><span class="line">    var page = 100;</span><br><span class="line">    <span class="built_in">return</span> <span class="function"><span class="title">function</span></span>()&#123;</span><br><span class="line">        this.auther = <span class="string">&#x27;dava&#x27;</span>;</span><br><span class="line">        this.price = 200;</span><br><span class="line">        this._page = <span class="function"><span class="title">function</span></span>()&#123;</span><br><span class="line">            <span class="built_in">return</span> page</span><br><span class="line">        &#125;    </span><br><span class="line">    &#125;</span><br><span class="line">&#125;)();</span><br><span class="line">var a = new book();</span><br><span class="line">console.log(a.auther)</span><br><span class="line">console.log(a.price)</span><br><span class="line">console.log(a.page)</span><br><span class="line">console.log(a._page())</span><br></pre></td></tr></table></figure>
<p>这里例子用了一个函数自动执行，一上来就执行了一个匿名函数，并且在匿名函数里面定义了一个局部变量page,然后又返回了一个匿名函数，并且被全局作用域下的book变量接收，此时使用new 调用book就会生成一个新对象a。其中auther属性和price属性可以直接通过对象访问，因为这些属性都是new的时候直接定义在返回的对象身上的,而page属性则没有，因此不能反回，但此时如果我想访问page属性，那就得依靠闭包了，返回的函数在外层的匿名函数里面，因此在返回的函数身上定义了一个方法叫_page，这个方法弹出了page属性，按照js作用域的关系，当前作用域找不到page，就会到上层作用域去寻找，这样就找到了。通过这种方式我们就把私有方法和公有方法区分开了。</p>
<p> 4、偏函数与柯里化<br>柯里化是把接受 n 个参数的 1 个函数改造为只接受 1个参数的 n 个互相嵌套的函数的过程。也就是 fn(a,b,c)fn (a, b, c)fn(a,b,c) 会变成 fn(a)(b)(c)fn (a)(b)(c)fn(a)(b)(c)。且看代码</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">function</span> generateName(prefix, <span class="built_in">type</span>, itemName) &#123;</span><br><span class="line">    <span class="built_in">return</span> prefix + <span class="built_in">type</span> + itemName</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>但是有时候业务分化的比较细，可能每个小组只需要传其中的一个参数，但是我们却不得把其余参数在传一次，我们就可以利用闭包存储变量的特性进行改造。成为以下这个样子</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">function</span> generateName(prefix) &#123;  </span><br><span class="line">    <span class="built_in">return</span> <span class="keyword">function</span>(<span class="built_in">type</span>) &#123;</span><br><span class="line">        <span class="built_in">return</span> <span class="keyword">function</span> (itemName) &#123;</span><br><span class="line">            <span class="built_in">return</span> prefix + <span class="built_in">type</span> + itemName</span><br><span class="line">        &#125;    </span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">// 生成大卖网商品名专属函数</span><br><span class="line">var salesName = generateName(<span class="string">&#x27;大卖网&#x27;</span>)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">// 记住prefix，生成大卖网母婴商品名专属函数</span><br><span class="line">var salesBabyName = salesName(<span class="string">&#x27;母婴&#x27;</span>)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">// 记住prefix和<span class="built_in">type</span>，生成洗菜网生鲜商品名专属函数</span><br><span class="line">var vegFreshName = generateName(<span class="string">&#x27;洗菜网&#x27;</span>)(<span class="string">&#x27;生鲜&#x27;</span>)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">// 输出 <span class="string">&#x27;大卖网母婴奶瓶&#x27;</span></span><br><span class="line">salesBabyName(<span class="string">&#x27;奶瓶&#x27;</span>)</span><br><span class="line"></span><br><span class="line">// 输出 <span class="string">&#x27;洗菜网生鲜菠菜&#x27;</span></span><br><span class="line">vegFreshName(<span class="string">&#x27;菠菜’)</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">// 啥也不记，直接生成一个商品名</span></span><br><span class="line"><span class="string">var itemFullName = generateName(&#x27;</span>洗菜网<span class="string">&#x27;)(&#x27;</span>生鲜<span class="string">&#x27;)(&#x27;</span>菠菜<span class="string">&#x27;)</span></span><br></pre></td></tr></table></figure>
<p>我们看到，在新的 generateName 函数中，我们可以以自由变量的形式将 prefix、type 的值保留在 generateName 内部的两层嵌套的外部作用域里。<br>这样一来，原有的 generateName (prefix, type, name) 现在经过柯里化已经变成了 generateName (prefix)(type)(itemName)。通过后者这种形式，我们可以选择性地决定是否要 “记住” prefix、type，从而即时地生成更加符合我们预期的、复用程度更高的目标函数。此外，柯里化还可以帮助我们以嵌套的形式把多个函数的能力组合到一起，这就是柯里化的魅力。</p>
<p>5、偏函数<br>偏函数和柯里化类似实现方法也类似，直接上代码无需多言</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">function</span> generateName(prefix, <span class="built_in">type</span>, itemName) &#123;</span><br><span class="line">    <span class="built_in">return</span> prefix + <span class="built_in">type</span> + itemName</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">// 调用时一口气传入3个入参</span><br><span class="line">var itemFullName = generateName(<span class="string">&#x27;大卖网&#x27;</span>, <span class="string">&#x27;母婴&#x27;</span>, <span class="string">&#x27;奶瓶&#x27;</span>)</span><br></pre></td></tr></table></figure>
<p>改造下：</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">function</span> generateName(prefix) &#123;</span><br><span class="line">    <span class="built_in">return</span> <span class="keyword">function</span>(<span class="built_in">type</span>, itemName) &#123;</span><br><span class="line">        <span class="built_in">return</span> prefix + <span class="built_in">type</span> + itemName</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">// 把3个参数分两部分传入</span><br><span class="line">var itemFullName = generateName(<span class="string">&#x27;大卖网&#x27;</span>)(<span class="string">&#x27;母婴&#x27;</span>, <span class="string">&#x27;奶瓶&#x27;</span>)</span><br></pre></td></tr></table></figure>
<p>要注意的一些点<br>由于闭包会使得函数中的变量都被保存在内存中，会消耗一定的内存，所以不能滥用闭包，否则会造成网页的性能问题。解决方法是，在退出函数之前，将不使用的局部变量全部删除。<br>闭包会在父函数外部，改变父函数内部变量的值。所以，如果你把父函数当作对象（object）使用，把闭包当作它的公用方法（Public Method），把内部变量当作它的私有属性（private value），这时一定要小心，不要随便改变父函数内部变量的值。</p>

      
    </div>
    <footer class="article-footer">
      <a data-url="http://example.com/2023/03/26/%E9%97%AD%E5%8C%85/" data-id="clfziy0ou000np5r4hp7c2o0o" data-title="闭包" class="article-share-link">Share</a>
      
      
      
    </footer>
  </div>
  
    
<nav id="article-nav">
  
    <a href="/2023/03/29/%E6%95%B0%E6%8D%AE%E5%8F%98%E6%9B%B4%E7%9A%84%E7%9B%91%E6%B5%8B/" id="article-nav-newer" class="article-nav-link-wrap">
      <strong class="article-nav-caption">Newer</strong>
      <div class="article-nav-title">
        
          数据变更的监测
        
      </div>
    </a>
  
  
    <a href="/2023/03/21/instanceof%E5%8E%9F%E7%90%86/" id="article-nav-older" class="article-nav-link-wrap">
      <strong class="article-nav-caption">Older</strong>
      <div class="article-nav-title">instanceof原理</div>
    </a>
  
</nav>

  
</article>


</section>
        
          <aside id="sidebar">
  
    

  
    
  <div class="widget-wrap">
    <h3 class="widget-title">Tags</h3>
    <div class="widget">
      <ul class="tag-list" itemprop="keywords"><li class="tag-list-item"><a class="tag-list-link" href="/tags/VUE/" rel="tag">VUE</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/js%E5%9F%BA%E7%A1%80/" rel="tag">js基础</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/%E5%B0%8F%E7%A8%8B%E5%BA%8F-uniapp/" rel="tag">小程序&#x2F;uniapp</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/%E6%B7%B7%E5%90%88%E5%BC%80%E5%8F%91/" rel="tag">混合开发</a></li></ul>
    </div>
  </div>


  
    
  <div class="widget-wrap">
    <h3 class="widget-title">Tag Cloud</h3>
    <div class="widget tagcloud">
      <a href="/tags/VUE/" style="font-size: 15px;">VUE</a> <a href="/tags/js%E5%9F%BA%E7%A1%80/" style="font-size: 20px;">js基础</a> <a href="/tags/%E5%B0%8F%E7%A8%8B%E5%BA%8F-uniapp/" style="font-size: 10px;">小程序/uniapp</a> <a href="/tags/%E6%B7%B7%E5%90%88%E5%BC%80%E5%8F%91/" style="font-size: 10px;">混合开发</a>
    </div>
  </div>

  
    
  <div class="widget-wrap">
    <h3 class="widget-title">Archives</h3>
    <div class="widget">
      <ul class="archive-list"><li class="archive-list-item"><a class="archive-list-link" href="/archives/2023/04/">April 2023</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2023/03/">March 2023</a></li></ul>
    </div>
  </div>


  
    
  <div class="widget-wrap">
    <h3 class="widget-title">Recent Posts</h3>
    <div class="widget">
      <ul>
        
          <li>
            <a href="/2023/04/02/%E5%B0%8F%E7%A8%8B%E5%BA%8F%E7%99%BB%E5%BD%95%E8%AE%BE%E8%AE%A1/">小程序登录设计</a>
          </li>
        
          <li>
            <a href="/2023/03/30/%E8%A7%82%E5%AF%9F%E8%80%85%E6%A8%A1%E5%BC%8F/">vue中的观察者模式</a>
          </li>
        
          <li>
            <a href="/2023/03/29/%E6%95%B0%E6%8D%AE%E5%8F%98%E6%9B%B4%E7%9A%84%E7%9B%91%E6%B5%8B/">数据变更的监测</a>
          </li>
        
          <li>
            <a href="/2023/03/26/%E9%97%AD%E5%8C%85/">闭包</a>
          </li>
        
          <li>
            <a href="/2023/03/21/instanceof%E5%8E%9F%E7%90%86/">instanceof原理</a>
          </li>
        
      </ul>
    </div>
  </div>

  
</aside>
        
      </div>
      <footer id="footer">
  
  <div class="outer">
    <div id="footer-info" class="inner">
      
      &copy; 2023 mobeiyanyun<br>
      Powered by <a href="https://hexo.io/" target="_blank">Hexo</a>
    </div>
  </div>
</footer>

    </div>
    <nav id="mobile-nav">
  
    <a href="/" class="mobile-nav-link">Home</a>
  
    <a href="/archives" class="mobile-nav-link">Archives</a>
  
</nav>
    


<script src="/js/jquery-3.4.1.min.js"></script>



  
<script src="/fancybox/jquery.fancybox.min.js"></script>




<script src="/js/script.js"></script>





  </div>
</body>
</html>